{#
  Macro that takes an array of config dictionaries, iterates over them and for each swimlane:
  - creates a dictionary with the original attributes
  - adds derived attributes to the dictionary
  - passes this dictionary in a callback method to the caller
  - renders the result of a callback method

  Each config in the input parameter array is a dictionary with the following attributes:
  - 'gp_ver'   : major Greenplum version
  - 'build_os' : the name of the OS for building PXF artifacts
  - 'test_os'  : the name of the OS for testing  PXF artifacts
  - 'os_ver'   : the version of the OS
  - 'test_fdw' : whether to test PXF FDW extension in this configuration

  Additional derived attributes added to the "x" context dictionary:
  - 'build_platform'     : the name and version of the OS for building PXF artifacts
  - 'test_platform'      : the name and version of the OS for testing  PXF artifacts
  - 'pkg_type'           : the type of the PXF artifact package (rpm or deb)
  - 'pkg_arch'           : the machine architecture of the package (x86_64 or amd64)
  - 'release_platform'   : the platform used in PXF  artifact file names (el7, el8, el9, ubuntu18.04)
  - 'greenplum_platform' : the platform used in GPDB artifact file names (rhel7, rhel8, el9, ubuntu18.04)
  - 'pxf_platform_infix' : the symbol separating the platform in the PXF artifact names
#}
{% macro for_each_config(configs) %}
    {% for conf in configs %}
        {# set local variables for a given loop iteration #}
        {% set x = dict(conf) %}
        {% do x.update({'build_platform': x.build_os ~ x.os_ver}) %}
        {% do x.update({'test_platform' : x.test_os  ~ x.os_ver}) %}

        {# set OS specific variable values #}
        {% if conf.test_os in [ 'ubuntu' ] %}
            {% do x.update({'pkg_type': 'deb'}) %}
            {% do x.update({'pkg_arch': 'amd64'}) %}
            {% do x.update({'release_platform': 'ubuntu' ~ x.os_ver}) %}
            {% do x.update({'pxf_platform_infix': '-'}) %}
            {% do x.update({'pxf_release_repackage_image': 'gpdb' ~ x.gp_ver ~ '-pxf-dev-' ~ x.build_platform ~ '-image' }) %}
        {% else %} {# other operating systems: centos, rocky and oel #}
            {% do x.update({'pkg_type': 'rpm'}) %}
            {% do x.update({'pkg_arch': 'x86_64'}) %}
            {% do x.update({'release_platform': 'el' ~ x.os_ver}) %}
            {% do x.update({'pxf_platform_infix': '.'}) %}
            {% do x.update({'pxf_release_repackage_image': 'rpmrebuild-' ~ x.build_platform ~ '-image' }) %}
        {% endif %}

        {# adjust Greenplum release platform due to historical inconsistencies #}
        {% if x.gp_ver in ['5', '6'] and x.release_platform.startswith('el') %}
            {% do x.update({'greenplum_platform': 'rh' ~ x.release_platform}) %}
        {% else %}
            {% do x.update({'greenplum_platform': x.release_platform}) %}
        {% endif %}

        {# create known filename regexes #}
        {% do x.update({'pxf_tarball_filename_regex':     'pxf-gp'     ~ x.gp_ver ~ '-*' ~ x.pxf_platform_infix ~ x.release_platform ~ '.tar.gz'}) %}
        {% do x.update({'pxf_fdw_tarball_filename_regex': 'pxf-fdw-gp' ~ x.gp_ver ~ '-*' ~ x.pxf_platform_infix ~ x.release_platform ~ '.tar.gz'}) %}

        {% do x.update({'pxf_release_package_filename_regex': 'pxf-gp' ~ x.gp_ver ~ '-*-2' ~ x.pxf_platform_infix ~ x.release_platform ~ x.pxf_platform_infix ~ x.pkg_arch ~ '.' ~ x.pkg_type }) %}
        {% if x.generate_release_tarball is sameas true %}
            {% do x.update({'pxf_release_tarball_filename_regex': 'pxf-gp' ~ x.gp_ver ~ '-*-' ~ x.release_platform ~ x.pxf_platform_infix ~ x.pkg_arch ~ '.tar.gz'}) %}
        {% endif %}

        {# create known resource names #}
        {% do x.update({'build_image_resource_name': 'gpdb' ~ x.gp_ver ~ '-pxf-dev-' ~ x.build_platform ~ '-image'}) %}
        {% do x.update({'test_image_resource_name':  'gpdb' ~ x.gp_ver ~ '-pxf-dev-' ~ x.test_platform  ~ '-image'}) %}
        {% do x.update({'gpdb_package_resource_name': 'gpdb' ~ x.gp_ver ~ '-' ~ x.release_platform ~ '-' ~ x.pkg_type ~ '-latest-0'}) %}
        {% do x.update({'pxf_tarball_resource_name': 'pxf-gp' ~ x.gp_ver ~ '-tarball-' ~ x.release_platform}) %}
        {% if x.test_fdw is sameas true %}
            {% do x.update({'pxf_fdw_tarball_resource_name': 'pxf-fdw-gp' ~ x.gp_ver ~ '-tarball-' ~ x.release_platform}) %}
        {% endif %}

        {# render the result of callback passing the resulting context specific to this loop iteration #}
[[caller(x)]]
    {% endfor %}
{% endmacro %}

{#
  Macro that takes an array of config dictionaries and groups them by the Greenplum version.
  For each Greenplum version, it
    - Creates a dictionary with the following attributes
      - 'gp_ver'    : the Greenplum majar version
      - 'platforms' : a list of all platforms for this Greenplum major version; a single platform is a dictionary with
        - 'greenplum_platform' : the platform used in GPDB artifact file names (rhel7, rhel8, el9, ubuntu18.04)
        - 'release_platform'   : the platform used in PXF artifact file names (el7, el8, el9, ubuntu18)
        - 'pkg_type'           : the type of the PXF artifact package (rpm or deb)
        - 'pkg_arch'           : the machine architecture of the package (x86_64 or amd64)
        - 'gpdb_package_resource_name' : resource name (without index) for GPDB package
        - 'gpdb_package_file_name'     : file name (with version placeholder) for GPDB package
        - 'gpdb_package_file_glob'     : file glob for uploading ('put') the downloaded GPDB package to cloud storage
    - Passes this dictionary in a callback method to the caller
    - Renders the result of a callback method
 #}
{% macro for_each_gp_ver(configs) %}
    {% for gp_ver, platforms in configs | groupby('gp_ver') %}
        {% set x = dict({'gp_ver': gp_ver}) %}
        {% do x.update({'platforms': []}) %}
        {% for p in platforms %}
            {% set y = dict() %}
            {% if p.build_os in [ 'centos', 'rocky' ] %}
                {% do y.update({'release_platform':   'el' ~ p.os_ver}) %}
                {% do y.update({'pkg_type':           'rpm'}) %}
                {% do y.update({'pkg_arch':           'x86_64'}) %}
            {% else %}
                {% do y.update({'release_platform':   'ubuntu' ~ p.os_ver}) %}
                {% do y.update({'pkg_type':           'deb'}) %}
                {% do y.update({'pkg_arch':           'amd64'}) %}
            {% endif %}

            {# adjust Greenplum release platform due to historical inconsistencies #}
            {% if x.gp_ver in ['5', '6'] and y.release_platform.startswith('el') %}
                {% do y.update({'greenplum_platform': 'rh' ~ y.release_platform}) %}
            {% else %}
                {% do y.update({'greenplum_platform': y.release_platform}) %}
            {% endif %}

            {% do y.update({'gpdb_package_resource_name':   "gpdb" ~ x.gp_ver ~ "-" ~ y.release_platform ~ "-" ~ y.pkg_type ~ "-latest"}) %}
            {% do y.update({'gpdb_package_file_name':       "greenplum-db-GPDB_VERSION-" ~ y.greenplum_platform ~ "-" ~ y.pkg_arch ~ "." ~ y.pkg_type}) %}
            {% do y.update({'gpdb_package_file_glob':       y.gpdb_package_file_name | replace("GPDB_VERSION", x.gp_ver ~ ".*")}) %}
            {% do x.platforms.append(y) %}
        {% endfor %}
        {# render the result of the callback passing the resulting context specific to this loop iteration #}
[[caller(x)]]
    {% endfor %}
{% endmacro %}

{# ----- ANCHOR macros ----- #}
{% macro anchor_destroy_dataproc(cluster_index) %}
    {% include 'anchors/destroy-dataproc-tpl.yml' %}
{% endmacro %}

{% macro anchor_destroy_cluster(cluster_type) %}
    {% include 'anchors/destroy-cluster-tpl.yml' %}
{% endmacro %}

{% macro anchor_gchat_notification(use_gchat) %}
    {% include 'anchors/gchat-alert-tpl.yml' %}
{% endmacro %}

{# ----- RESOURCE TYPES macros ----- #}
{% macro resource_type_registry_image(image_name, image_repository, image_tag) %}
    {% set resource_type = true %}
    {% include 'resources/registry-image-tpl.yml' %}
{% endmacro %}

{# ----- RESOURCES macros ----- #}
{% macro resource_pxf_dependencies(dependency_type) %}
    {% include 'resources/pxf-dependencies-tpl.yml' %}
{% endmacro %}

{% macro resource_singlecluster(hadoop_distro) %}
    {% include 'resources/singlecluster-tpl.yml' %}
{% endmacro %}

{% macro resource_github_repo(repo_name) %}
    {% include 'resources/github-repo-tpl.yml' %}
{% endmacro %}

{% macro resource_gchat_notification(alert_name, url_key) %}
    {% include 'resources/gchat-notification-tpl.yml' %}
{% endmacro %}

{% macro resource_registry_image(image_name, image_repository, image_tag) %}
    {% set resource_type = false %}
    {% include 'resources/registry-image-tpl.yml' %}
{% endmacro %}

{% macro resource_pxf5_gp6_el7_artifact() %}
    {% include 'resources/pxf5-gp6-el7-artifact-tpl.yml' %}
{% endmacro %}

{% macro resource_pxf6_minor_rpm_artifact(minor_ver, gp_ver, platform_ver) %}
    {% include 'resources/pxf6_minor-rpm-artifact-tpl.yml' %}
{% endmacro %}

{% macro resource_terraform(cluster_type) %}
    {% include 'resources/terraform-tpl.yml' %}
{% endmacro %}

{% macro shipit_file(environment) %}
    {% include 'resources/release-shipit-tpl.yml' %}
{% endmacro %}

{% macro resource_timer(name, interval) %}
    {% include 'resources/timer-tpl.yml' %}
{% endmacro %}

{# ----- JOB macros ----- #}
{% macro job_group(group_name, job_list) %}
    {% include 'jobs/job-groups-tpl.yml' %}
{% endmacro %}

{% macro reset_passed_jobs(configs, job_names) %}
    {% call(x) for_each_config(configs) %}
        {% do job_names.images.update({x.test_image_resource_name : []}) %}
        {% do job_names.tarballs.update({x.pxf_tarball_resource_name : []}) %}
        {% do job_names.gpdb_packages.update({x.gpdb_package_resource_name : []}) %}
    {% endcall %}
{% endmacro %}

{% macro add_test_job(file_name, x, job_names, extra_list_name, gchat_notification) %}
    {% include file_name %}
    {% do job_names.all.append(x.job_name) %}

    {% do job_names.images.update({x.test_image_resource_name: job_names.images[x.test_image_resource_name] + [x.job_name]}) %}
    {% do job_names.tarballs.update({x.pxf_tarball_resource_name: job_names.tarballs[x.pxf_tarball_resource_name] + [x.job_name]}) %}
    {% do job_names.gpdb_packages.update({x.gpdb_package_resource_name: job_names.gpdb_packages[x.gpdb_package_resource_name] + [x.job_name]}) %}

    {% do job_names.tests.update({extra_list_name: job_names.tests[extra_list_name] + [x.job_name]}) %}
{% endmacro %}

{% macro add_gate_job(file_name, job_names, env_var, build_test_pxf_combinations, pxf_release_repackage_images, gchat_notification) %}
    {# set a fake dictionary so that the job can populate the job_name #}
    {% set x = dict() %}
    {% set environment = env_var %}
    {% include file_name %}
    {% do job_names.all.append(x.job_name) %}
{% endmacro %}
